Don't use Resolve.root when checking for cycles
authorAleksey Kladov <aleksey.kladov@gmail.com>
Wed, 17 Aug 2016 20:31:29 +0000 (23:31 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 18 Aug 2016 18:49:34 +0000 (21:49 +0300)
src/cargo/core/resolver/mod.rs
tests/build.rs

index c774481f1888e1df6ef35ce4661b09b9ce5aead2..d796a5c7241fdd307fd6ef317e536846706cc411 100644 (file)
@@ -980,15 +980,24 @@ impl<'a> Context<'a> {
 fn check_cycles(resolve: &Resolve,
                 activations: &HashMap<(String, SourceId), Vec<Rc<Summary>>>)
                 -> CargoResult<()> {
-    let mut summaries = HashMap::new();
-    for summary in activations.values().flat_map(|v| v) {
-        summaries.insert(summary.package_id(), &**summary);
+    let summaries: HashMap<&PackageId, &Summary> = activations.values()
+        .flat_map(|v| v)
+        .map(|s| (s.package_id(), &**s))
+        .collect();
+
+    // Sort packages to produce user friendly deterministic errors.
+    let all_packages = resolve.iter().collect::<BinaryHeap<_>>().into_sorted_vec();
+    let mut checked = HashSet::new();
+    for pkg in all_packages {
+        if !checked.contains(pkg) {
+            try!(visit(resolve,
+                       pkg,
+                       &summaries,
+                       &mut HashSet::new(),
+                       &mut checked))
+        }
     }
-    return visit(resolve,
-                 resolve.root(),
-                 &summaries,
-                 &mut HashSet::new(),
-                 &mut HashSet::new());
+    return Ok(());
 
     fn visit<'a>(resolve: &'a Resolve,
                  id: &'a PackageId,
index 4f74335b8c5ecd3bcd1b9f3ce6c34dbb122a11b5..4844eae5362d1c83c419fc78d10f21d970b7aaf2 100644 (file)
@@ -1887,7 +1887,7 @@ fn cyclic_deps_rejected() {
     assert_that(p.cargo_process("build").arg("-v"),
                 execs().with_status(101)
                        .with_stderr("\
-[ERROR] cyclic package dependency: package `foo v0.0.1 ([..])` depends on itself
+[ERROR] cyclic package dependency: package `a v0.0.1 ([..])` depends on itself
 "));
 }